#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import pexpect

from common.common import execute_cmd
from common.const import CMDResult
from common.util.cmd_utils import cmd_format
from generaldb.gbase8a import LOGGER
from generaldb.gbase8a.common.const import CmdStr


class GcrcmanTool:
    def __init__(self, host_name, host_pwd, db_pwd, gcluster_base_path, timeout=30):
        self._timeout = timeout
        self._host_pwd = host_pwd
        self._host_name = host_name
        self._db_pwd = db_pwd
        self._gcluster_base_path = gcluster_base_path

    def run_gcrcman_tool(self, path, gcrcman_cmd):
        cmd = cmd_format(CmdStr.LOGIN_GCRCMAN, self._host_name, self._gcluster_base_path, path)
        LOGGER.info("cmd:%s, gcrcman_cmd:%s", cmd, gcrcman_cmd)
        child = pexpect.spawn(cmd, timeout=self._timeout, )
        expect_code = 0
        create_socket_code = child.expect(["Host Password", pexpect.TIMEOUT, pexpect.EOF])
        if create_socket_code != expect_code:
            return False, f"{child.before.decode()}, {child.after.decode()}"
        child.sendline(s=self._host_pwd)
        code = child.expect(["Database Password", pexpect.TIMEOUT, pexpect.EOF])
        if code != expect_code:
            return False, f"{child.before.decode()}, {child.after.decode()}"
        child.sendline(s=self._db_pwd)
        code = child.expect(["gcrcman>", "database passwd is wrong", "error",
                             "host password wrong", pexpect.TIMEOUT, pexpect.EOF])
        if code != expect_code:
            child.close()
            return False, f"{child.before.decode()}, {child.after.decode()}"
        child.sendline(s=gcrcman_cmd)
        code = child.expect(["gcrcman>", pexpect.TIMEOUT, pexpect.EOF])
        if code != expect_code:
            child.close()
            LOGGER.error("Login gcrcman failed")
            return False, f"{child.before.decode()}, {child.after.decode()}"
        result = child.before.decode()
        child.close()
        cmd = CmdStr.EXEC_RESULT_CODE
        res, out, err = execute_cmd(cmd)
        if res != CMDResult.SUCCESS:
            return False, result
        return True, result
